package com.zxcl.service.impl;


import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zxcl.constant.HttpConstant;
import com.zxcl.constant.MqConstant;
import com.zxcl.domain.Member;
import com.zxcl.dto.MemberUpdateDTO;
import com.zxcl.dto.PhoneDTO;
import com.zxcl.ex.BusinessException;
import com.zxcl.mapper.MemberMapper;
import com.zxcl.model.AliSmsModel;
import com.zxcl.service.MemberService;
import com.zxcl.utils.AuthUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
@Log4j2
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    /**
     * 更新会员的信息
     *
     * @param memberUpdateDTO
     * @return
     */
    @Override
    public Integer updateMember(MemberUpdateDTO memberUpdateDTO) {
        Long userId = AuthUtil.getUserId();
        Member member = new Member();
        member.setId(userId.intValue());
        member.setPic(memberUpdateDTO.getPic());
        // 乱码问题  转码 8F7SE8D7A8F%545Q&^KSAH 注意编码字符集 utf-8mb4
        String encode = null;
        try {
            encode = URLEncoder.encode(memberUpdateDTO.getNickName(), HttpConstant.UTF_8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        member.setNickName(encode);
        member.setUpdateTime(new Date());
        return getBaseMapper().updateById(member);
    }

    /**
     * 发送验证码
     *  向MQ里面发  AliSmsModel 的JSON数据
     * @param phoneDTO
     */
    @Override
    public void sendPhoneCode(PhoneDTO phoneDTO) {
        String phonenum = phoneDTO.getPhonenum();
        //set nx
        Boolean flag = redisTemplate.opsForValue().setIfAbsent( "sms_control:"+ phonenum, "", Duration.ofSeconds(60));
        if(!flag){
            throw new BusinessException("您太快了。慢点");
        }
        AliSmsModel model=new AliSmsModel();
        model.setPhoneNumber(phoneDTO.getPhonenum());
        model.setOpenId(AuthUtil.getOpenId());
        model.setSignName("MALL");
        model.setTemplateCode("SMS_462390373");
        Map<String,String> params=new HashMap<>();
        String code = createCode();
        params.put("code",code);
        model.setTemplateParam(JSON.toJSONString(params));

        //把正确的验证码放到redis
        redisTemplate.opsForValue().set("sms_code:"+phoneDTO.getPhonenum(),code,3, TimeUnit.MINUTES);



        //向MQ里面发消息
        SendResult sendResult = rocketMQTemplate.syncSend(MqConstant.ALI_SMS_TOPIC, JSON.toJSONString(model));
        log.info("发送短信，手机号为:{},mq接收结果为:{}", phoneDTO.getPhonenum(), sendResult.getSendStatus());
    }




    private Random random=new Random();

    /**
     * 生成一个4位的随机数
     */
    private String createCode() {
        // 4位   1000  - 9998
        int i = random.nextInt(9000) + 1000;
        return String.valueOf(i);
    }


    @Override
    public Integer savePhone(PhoneDTO phoneDTO) {
        //得到手机号
        String phonenum = phoneDTO.getPhonenum();
        //得到用户输入的验证码
        String inputCode = phoneDTO.getCode();
        //得到redis里面正确的验证码
        String realCode = this.redisTemplate.opsForValue().getAndDelete("sms_code:" + phonenum);
        if (ObjectUtils.isEmpty(realCode)) {
            throw new BusinessException("验证码已经失效，请重新获取");
        }
        if (!inputCode.equals(realCode)) {
            throw new BusinessException("验证码错误，请重新获取");
        }
        Member member = new Member();
        Long userId = AuthUtil.getUserId();
        member.setId(userId.intValue());
        member.setUserMobile(phonenum);
        member.setUpdateTime(new Date());
        int i = getBaseMapper().updateById(member);
        log.info("更新会员手机号完成，手机号为:{},会员ID为:{},状态为:{}", phonenum,userId,i>0);
        return i;
    }
}
